home *** CD-ROM | disk | FTP | other *** search
- /* PROGRAM rTutor */
- /* (a home-grown tutorial for writing applications using resources */
- /* Part 1 - starting up & shutting down the tools from a ToolStartup */
- /* list kept in a resource */
- /* Part 2 - add a menu bar that is kept in a resource */
- /* Part 3 - add the event loop so that the menus "come alive" and put up a */
- /* window that is defined in the resource fork */
- /* Part 3.2 - change "About" box from a simple beep into an Alert Window and */
- /* redo the Rez and MAKE file so that we can avoid re-compiling */
- /* the the parts that haven't changed and also to show off some */
- /* of Rez's special abilities such as including already compiled */
- /* resources from another file and appending Rez's output to an */
- /* already existing resource without wiping out the existing */
- /* resources... */
- /* Part 3.3 - tossed out the seperate Rez file that showed how to include */
- /* pre-compiled resources and the "-a" flag. If you want to know */
- /* how those are done, see Part 3.2's source. I also tossed the */
- /* controls out of the window and put some icons in the window. */
- /* Naturally, the icons are stored as resources. I've also */
- /* slipped in a special cursor that's kept as a resource also - */
- /* mainly to show people how to use the current definition of how */
- /* an rCursor should be defined (the bit map for an rCursor is */
- /* done differently from the bitmap for an rIcon). */
- /* Part 3.5 - tossed out the custom cursor (it was put in partially just to */
- /* show how to do it). Added lots of new icons (used in drawing */
- /* the "levels" and two custom resource types. Big change this */
- /* time around is the "automating" of the icon drawing - in */
- /* Part 3.3, we hard coded a bunch of calls to "DrawIcon" right */
- /* here in the main source code (ugh). This time, we've changed */
- /* the main source to draw as many icons where ever we want them. */
- /* See the detailed docs for how and why this was done. */
-
- #include <types.h>
- #include <INTMATH.h>
- #include <MEMORY.h>
- #include <MISCTOOL.h>
- #include <LOCATOR.h>
- #include <DESK.H>
- #include <QUICKDRAW.h>
- #include <EVENT.h>
- #include <CONTROL.h>
- #include <WINDOW.h>
- #include <MENU.h>
- #include <GSOS.h>
- #include <Resources.h>
- #include <QDAux.h> /* added for part 3.3 */
-
- #define kStartStopID 1L /* used when starting and shutting down tools */
-
- /*---------------------- Menus & Menu Bars ---------------------------*/
- #define kMenuBarID 1L /* resource ID of the menu bar itself */
-
- /* define all the menu id's */
- #define kAppleMenuID 1000 /* resource ID of the Apple menu */
- #define kFileMenuID 2000 /* resource ID of the File menu */
- #define kEditMenuID 3000 /* resource ID of the Edit menu */
-
- /* now, define the menu item id's */
- #define kAboutBoxID 1001 /* resource ID of the About Box menu item */
-
- #define kNewItemID 2001 /* resource ID of the New Item in File menu */
- #define kOpenItemID 2002 /* resource ID of the Open item in File menu */
- #define kCloseItemID 255 /* the "Close" item */
- #define kSaveItemID 2004 /* the "Save" item */
- #define kSaveAsItemID 2005 /* the "Save As..." item */
- #define kRevertItemID 2006 /* the "Revert to Saved" item */
- #define kPageItemID 2007 /* the "Page Setup..." item */
- #define kPrintItemID 2008 /* the "Print..." item */
- #define kQuitItemID 2009 /* the "Quit" item */
-
- #define kUndoItemID 250 /* the "Undo" item */
- #define kCutItemID 251 /* the "Cut" item */
- #define kCopyItemID 252 /* the "Copy" item */
- #define kPasteItemID 253 /* the "Paste" item */
- #define kClearItemID 254 /* the "Clear" item */
- #define kSelectItemID 3001 /* the "Select All" item */
- #define kShowClipItemID 3002 /* the "Show ClipBoard" item */
-
- /* define the resource ID's for all windows used by this app */
- #define myWindowID 2362L /* window's resource ID = 2362 */
-
- /* declare the constants for our TaskMaster event mask */
- #define kMyTaskMask 0x001FFFFFL /* this mask is for TaskMaster itself */
- #define kMyEventMask 0xFFFF /* this mask is passed to GetNextEvent */
-
- /* define the constant used to represent the icons */
- /* lots of new ones added for part 3.5 */
- #define kFloorIcon 1 /* ID of the icon used as the "floor" */
- #define kPoleIcon 2 /* for the up/down pole */
- #define kCoinIcon 3 /* gold coin */
- #define kGemIcon 4 /* diamond */
- #define kRockIcon 5 /* rock */
- #define kLeftIcon 6 /* man facing left */
- #define kRightIcon 7 /* man facing right */
- #define kCenterIcon 8 /* man facing forward */
- #define kLeft2Icon 9 /* icon for halfway between positions moving left */
- #define kRight2Icon 10 /* icon for halfway between positions moving right */
- #define kSplatIcon 11 /* icon for player that fell too far */
- #define kEraserIcon 255 /* solid white icon for erasing other icons */
-
- /* define constants for the new resource types we created */
- #define anIconUsedList 0x6002
- #define aSpotList 0x6003
-
- /* declare the structures for the new resource types so we can use them */
- struct Spot
- {
- Point whereItGoes; /* upper left corner of icon */
- int theRow; /* which row it's in */
- int theColumn; /* which column it's in */
- };
- typedef struct Spot Spot, *SpotPtr, **SpotHndl;
-
- struct SpotList
- {
- int numInList; /* number of items in the list */
- Spot spotArray[]; /* the array of spots */
- };
- typedef struct SpotList SpotList, *SpotListPtr, **SpotListHndl;
-
- struct IconUsedList
- {
- int numInList; /* number of icons in the list */
- int iconArry[]; /* the array of icons */
- };
- typedef struct IconUsedList IconUsedList, *IULPtr, **IULHndl;
-
- /* declare the global variable that we'll use with TaskMaster */
- WmTaskRec gMyEvent;
-
-
- /* declare all of the global variables that we'll be using */
- unsigned gMyMemID; /* holds the ID returned by MMStartup */
- Ref gToolListRef; /* list of tools used to start and stop the tools */
- Boolean gPunt; /* TRUE if it's time to quit the app */
- long gWhichLevel; /* indicates which "level" player is on */
- long gFacing; /* ID of icon being used for player */
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for putting up the About box */
-
- #define kAboutStr 100L /* define the constant for the About box's string */
-
- do_show_about()
- {
- /* change the beep into an Alert Window - grab the Alert from a resource */
- word pickedButton;
- pickedButton = AlertWindow(0x0004, /* alert string is in resource fork */
- /* and is a "C" string */
- NULL, /* not used right now */
- kAboutStr); /* resource ID of Alert's string */
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for quitting the app */
-
- do_quit_app()
- {
- /* we actually just set the "quit" flag and let the real quitting happen */
- /* in the main event loop. Later, we would add code here to cope with */
- /* closing all open windows, saving their contents, etc. */
-
- gPunt = TRUE;
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for dealing with items picked */
- /* from the menus by the user */
-
- do_menu_events()
- {
-
- unsigned int pickedMenuID; /*ID of menu the user just picked an item from */
- unsigned int pickedItemID; /* ID of item the user just picked */
-
- /* the hi-word of wmTaskData is the menu ID */
- pickedMenuID = HiWord(gMyEvent.wmTaskData);
-
- /* the lo-word of wmTaskData is the item ID */
- pickedItemID = LoWord(gMyEvent.wmTaskData);
-
- switch(pickedItemID)
- {
- case kAboutBoxID : do_show_about(); /* show the About box */
- break;
- case kNewItemID : break; /* that's all for this item */
- case kOpenItemID : break; /* that's all for this item */
- case kCloseItemID : break; /* that's all for this item */
- case kSaveItemID : break; /* that's all for this item */
- case kSaveAsItemID : break; /* that's all for this item */
- case kRevertItemID : break; /* that's all for this item */
- case kPageItemID : break; /* that's all for this item */
- case kPrintItemID : break; /* that's all for this item */
- case kQuitItemID : do_quit_app(); /* sets gPunt to TRUE */
- break;
- case kUndoItemID : break; /* that's all for this item */
- case kCutItemID : break; /* that's all for this item */
- case kCopyItemID : break; /* that's all for this item */
- case kPasteItemID : break; /* that's all for this item */
- case kClearItemID : break; /* that's all for this item */
- case kSelectItemID : break; /* that's all for this item */
- case kShowClipItemID : break; /* that's all for this item */
-
- default: ; /* always have a default action in case something goes wrong */
-
- } /* end of the "switch" statement */
-
- /* Turn off the highlighting on the menu the user picked the item from. */
- /* Then return to the main event loop to see what we'll do next. */
- HiliteMenu(FALSE,pickedMenuID);
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure installs the menu bar from a resource */
-
- do_make_menus()
- {
- MenuBarRecHndl my_mbar_hndl;
- word menu_bar_height;
- {
-
- /* the next three calls are ALL required to bring the menu bar in from */
- /* the resource fork AND make it the current system menu bar. For */
- /* details, see the IIGS Toolbox Reference, under NewMenuBar2 */
- my_mbar_hndl = NewMenuBar2(refIsResource, kMenuBarID, nil);
- SetSysBar(my_mbar_hndl);
- SetMenuBar(nil);
-
- /* now, add NDA's, adjust the sizes of the menus, and draw the menu bar */
- /* kAppleMenuID used to be defined as a long and had to be cast to a */
- /* word here. It's been redefined to be only a word in size, so the */
- /* casting is no longer needed. */
- FixAppleMenu(kAppleMenuID); /* adds NDA's */
- menu_bar_height = FixMenuBar(); /* adjust the sizes */
- DrawMenuBar(); /* draw the new menu bar and enjoy! */
- }
- }
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is responsible for starting the tools (using the */
- /* list in a resource) if the SartupTools call fails, then gPunt will */
- /* contain "TRUE", so we can abort the app the global variable for this */
- /* app's memory id is acquired here as well. */
-
- do_init_rom()
- {
- gMyMemID = _ownerid; /* find out our memory id & save it for later */
-
- /* crank 'em up! - make sure that kStartStopID is defined as a long!!! */
- gToolListRef = StartUpTools(gMyMemID,refIsResource,kStartStopID);
-
- if (_toolErr == noError)
- { /* there was no error, so the app can continue starting up */
- gPunt = FALSE;
- gWhichLevel = 1; /* start player on first level */
- }
- else
- { /* something went wrong, so set gPunt to indicate the failure */
- gPunt = TRUE;
- }
- }
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure draws the contents of the window that we created */
- /* from the template in the resource fork. Any time the window's content */
- /* region needs to be redrawn, this routine gets called. */
-
- drawMyContents()
- {
- /* declare a couple of local variables that we'll need */
-
- QDIconRecordHndl my_RHndl; /* handle to icon loaded from rFork */
- long my_icon_id; /* resource ID of icon to be used */
- int loop_counter1; /* take a guess :-) */
- int loop_counter2; /* another easy one */
- int how_many_icons; /* number of icons in a level */
- long my_temp; /* used for misc junk */
- IULHndl my_IULHndl; /* handle to list of icons on this lvl */
- SpotListHndl my_SLHndl; /* handle to list of spots to draw at */
- SpotListPtr my_SLPtr; /* just a spot list */
- int xLoc; /* x-axis location for icon drawing */
- int yLoc; /* y-axis location for icon drawing */
-
- my_IULHndl = (IULHndl) LoadResource(anIconUsedList,gWhichLevel);
-
- /* find out how many icons on this level */
- how_many_icons = (**my_IULHndl).numInList;
-
- for (loop_counter1 = 0; loop_counter1 < how_many_icons; loop_counter1++)
- {
- my_icon_id = (**my_IULHndl).iconArry[loop_counter1]; /* get ID of icon */
- my_temp = my_icon_id*0x10000 + gWhichLevel; /* calculate resource ID */
-
- /* load the spot list for this icon */
- my_SLHndl = (SpotListHndl) LoadResource(aSpotList, my_temp);
-
- /* load the icon from the rFork */
- my_RHndl = (QDIconRecordHndl) LoadResource(rIcon, my_icon_id);
-
- /* lock the handle and draw it at all locations in its spot list */
- HLock(my_SLHndl);
- my_SLPtr = *my_SLHndl; /* speed things up by dereferencing only once */
- for (loop_counter2 = 0; loop_counter2 < my_SLPtr->numInList;
- loop_counter2++)
- {
- DrawIcon(*my_RHndl, 0, my_SLPtr->spotArray[loop_counter2].whereItGoes.h,
- my_SLPtr->spotArray[loop_counter2].whereItGoes.v);
- }; /* end of for loop_counter2 */
- HUnlock(my_SLHndl);
- }; /* end of for loop_counter1 */
-
- } /* end of drawMyContents() */
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure creates a window using a template that is kept */
- /* in the application's resource fork */
-
- do_make_window()
- {
- /* since we only have one window and it can't be closed, we won't */
- /* bother to keep the grafPortPtr in a global. We can always get it */
- /* back by calling FrontWindow(). Later, when we add multiple windows, */
- /* we'll want a better way to keep track of the grafPortPtr to each */
- /* window, but for now I'd like to keep it simple. */
-
- GrafPortPtr myWndwPtr;
-
- myWndwPtr = NewWindow2(NIL, /* use "default" title string from param block */
- NIL, /* use "default" refCon from param block */
- drawMyContents, /* procedure that draws contents */
- NIL, /* use std def proc for this window */
- refIsResource, /* template is in a resource */
- myWindowID, /* resource ID of our window */
- rWindParam1); /* template is of param type 1 */
-
- SetPort(myWndwPtr); /* set the Graf Port to the newly created window's */
- }
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is the main event loop. It runs until gPunt is */
- /* set to TRUE by the user picking "Quit" from the File menu. */
-
- do_main_event()
- {
- word myTaskCode; /* used to hold the task codes returned by Task Master */
-
-
- /* tell Task Master which events it can do */
- /* we're lazy, so let it handle everything possible! */
- gMyEvent.wmTaskMask = kMyTaskMask;
-
- while(!gPunt) /* keep calling Task Master until "Quit" has been selected */
- {
- myTaskCode = TaskMaster(kMyEventMask, &gMyEvent);
- switch(myTaskCode)
- {
- case wInGoAway:
- break;
- case wInSpecial:
- case wInMenuBar:
- do_menu_events();
- break;
- default:
- break; /* always have a default */
- } /* end of the switch statement */
- } /* end of the "while" */
- } /* end of do_main_event */
-
-
- /* ------------------------------------------------------------------------ */
- /* the following procedure is the main application itself. */
- /* don't forget to add the code that will check the message center to see if */
- /* this app was launched by clicking on its icon or by clicking on a data */
- /* file created by this app. If the data file was clicked on, then grab its */
- /* name out of the message center and open it instead of opening the */
- /* untitled window. */
-
- main()
- {
- do_init_rom(); /* get my memory id, start the tools, & set gPunt */
- if (gPunt == FALSE)
- {
- do_make_menus(); /* insert the menu bar */
- do_make_window(); /* create a new window from the resource fork */
- InitCursor(); /* this changes the cursor to the "normal" one. */
- /* It was left as a watch cursor when the tools */
- /* were started up. */
-
- do_main_event();
- }
- ShutDownTools(refIsHandle,gToolListRef); /* shut down the tools and quit */
- } /* end of main program */
-